package org.example.JVM.ASM.Visitor;

import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: farprt
 * @create: 2022-11-16 16:51
 **/
@Getter
public class ClassWriter implements ClassVisitor {

    private int version;
    private String className;
    private String access;

    private List<FieldWriter> fieldWriters = new ArrayList<>();
    private List<MethodWriter> methodWriters = new ArrayList<>();

    @Override
    public void visit(int version, String access, String className) {
        this.version = version;
        this.className = className;
        this.access = access;
    }

    @Override
    public FieldVisitor visitField(String access, String name, String descriptor) {
        FieldWriter fieldWriter = new FieldWriter(access, name, descriptor);
        fieldWriters.add(fieldWriter);
        return fieldWriter;

    }

    @Override
    public MethodVisitor visitMethod(String access, String name, String descriptor) {
        MethodWriter methodWriter = new MethodWriter(access, name, descriptor);
        methodWriters.add(methodWriter);
        return methodWriter;
    }

    /**
     * @param
     * @return:
     * @Author: farprt
     * @date: 2022/11/16 16:56
     * @description: 模拟实现ASM框架的toByteArray方法，获取生成的类的class字节数组
     */
    public void showClass() {
        System.out.println("版本号:" + getVersion());
        System.out.println("访问标志:" + getAccess());
        System.out.println("类名:" + getClassName());

        for (FieldWriter fieldWriter : fieldWriters) {
            System.out.printf(fieldWriter.getAccess()
                    + " " + fieldWriter.getDescriptor()
                    + " " + fieldWriter.getName() + " ");
            for (String annotation : fieldWriter.getAnnotations()) {
                System.out.println(annotation + " ");
            }
        }

        for (MethodWriter methodWriter : methodWriters) {
            System.out.println(methodWriter.getAccess()
                    + " " + methodWriter.getName()
                    + " " + methodWriter.getDescriptor()
                    + "操作数栈大小:" + methodWriter.getMaxStackSize()
                    + "局部变量表大小:" + methodWriter.getMaxLocalSize());
        }
    }
}